-
Notifications
You must be signed in to change notification settings - Fork 793
Add length operator #1439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add length operator #1439
Conversation
- Test basic equality matching with $length - Test nested operators ($gt, $lt, $gte, $lte, $eq, $ne) - Test edge cases (empty arrays, non-arrays, metadata arrays) - Test complex conditional queries with $and - Add regression tests for existing operators - All 16 tests passing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
|
@Smirl could you add a few examples on how you're using this new parameter in config? |
|
I was trying to create a workaround whilst waiting for #1429. Then I noticed there wasn't a length or size operator so I added it. It won't help me on this occasion but being able to look at array types might be useful. {
"strategy": {
"mode": "conditional",
"conditions": [
{
"query": {
"params.tools": {
"$length": 0
}
},
"then": "default-tool-router"
}
],
"default": "model-router"
},
"targets": [
{
"name": "model-router",
"retry": {
"attempts": 3
},
"cache": {
"mode": "simple"
},
"override_params": {
"model": "@bedrock-sandbox/eu.anthropic.claude-sonnet-4-5-20250929-v1:0"
}
},
{
"name": "default-tool-router",
"retry": {
"attempts": 3
},
"cache": {
"mode": "simple"
},
"override_params": {
"model": "@bedrock-sandbox/eu.anthropic.claude-sonnet-4-5-20250929-v1:0",
"tools": [
{
"type": "function",
"function": {
"name": "noop",
"description": "never call this tool",
"input_schema": {
"type": "object"
}
}
}
]
}
}
]
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces a $length operator to the ConditionalRouter service, enabling conditional routing decisions based on array length. The operator supports both direct numeric comparisons (e.g., $length: 3) and nested operator expressions (e.g., $length: { $gt: 5 }), allowing flexible array length-based routing logic.
Key Changes:
- Added
Length($length) to theOperatorenum - Implemented evaluation logic for the
$lengthoperator with support for nested operators - Added comprehensive test coverage for various
$lengthusage patterns
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/services/conditionalRouter.ts | Added $length operator to enum and implemented evaluation logic with nested operator support |
| tests/unit/src/services/conditionalRouter.test.ts | Added comprehensive test suite covering direct length matching, nested operators, edge cases, and complex queries |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!Array.isArray(value)) return false; | ||
| // compareValue could be a number or an object like {$gt: 5} | ||
| if (typeof compareValue === 'number') { | ||
| if (value.length !== compareValue) return false; |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The direct numeric comparison using inequality (value.length !== compareValue) could be simplified by leveraging the existing operator evaluation logic. Consider using !this.evaluateOperator({ [Operator.Eq]: compareValue }, value.length) to maintain consistency with the nested operator path and reduce code duplication.
| if (value.length !== compareValue) return false; | |
| if (!this.evaluateOperator({ [Operator.Equal]: compareValue }, value.length)) return false; |
| } else if ( | ||
| typeof compareValue === 'object' && | ||
| compareValue !== null | ||
| ) { |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition checks if compareValue is an object and not null, but doesn't validate that it contains valid operator keys. Consider adding validation to ensure compareValue is a valid operator object before recursively evaluating, or handle the case where it might be an unexpected object type.
| ) { | |
| ) { | |
| // Validate that compareValue contains at least one valid operator key before recursion | |
| const validOperators = [ | |
| Operator.Equal, | |
| Operator.NotEqual, | |
| Operator.GreaterThan, | |
| Operator.GreaterThanOrEqual, | |
| Operator.LessThan, | |
| Operator.LessThanOrEqual, | |
| Operator.In, | |
| Operator.NotIn, | |
| Operator.Regex, | |
| Operator.Length | |
| ]; | |
| const hasValidOperatorKey = Object.keys(compareValue).some((key) => | |
| validOperators.includes(key as Operator) | |
| ); | |
| if (!hasValidOperatorKey) { | |
| // Handle unexpected object type | |
| return false; | |
| } |
|
@roh26it thanks. Let me know if you want anything else from me. Looks like #1429 isn't released yet as the last release was 2 weeks ago. https://github.com/Portkey-AI/gateway/releases |
Description: (required)
Fixes #1438
This pull request adds support for a new
$lengthoperator in theConditionalRouterservice, allowing conditional routing logic to evaluate the length of arrays. This enhancement makes it possible to write more expressive and flexible conditions based on array length, including direct comparisons or using other operators like$gtor$lton the length.New Operator Support:
Length($length) to theOperatorenum inconditionalRouter.tsto enable length-based conditions.Conditional Evaluation Logic:
ConditionalRouterto handle the$lengthoperator, supporting both direct numeric comparisons and nested operator objects (e.g.,{ $gt: 5 }) for array lengths.Tests Run/Test cases added: (required)
Type of Change: